package it.secse.idmadaption.plugin;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Iterator;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNode;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.axiom.om.impl.llom.util.AXIOMUtil;
import org.apache.axis2.AxisFault;
import org.apache.axis2.MyClient.MyServiceClient;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;
import org.apache.neethi.Policy;
import org.apache.neethi.PolicyEngine;
import org.apache.rampart.RampartMessageData;
import org.apache.rampart.policy.model.RampartConfig;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;

import it.secse.idmadaption.credential.CredentialData;
import it.secse.idmadaption.credential.UsrPassCredentialData;
import it.secse.idmadaption.policy.PolicyWrapper;
import it.secse.idmadaption.util.Constants;

public class WSSPlugin extends AbstractPlugin {

	OMElement policyCompleted = null;

	public Object manage(String operationName, String realEndPoint,
			Object clientRequest, CredentialData data, PolicyWrapper policy) {

		try {
			ConfigurationContext ctx = ConfigurationContextFactory
					.createConfigurationContextFromFileSystem(
							Constants.REPOSITORY_FOLDER, null);
			MyServiceClient client = new MyServiceClient(ctx, null);
			Options options = new Options();
			options.setAction("urn" + ":" + operationName);
			options.setTo(new EndpointReference(realEndPoint));

			StAXOMBuilder builder = new StAXOMBuilder(Constants.DEFAULT_DIR
					+ File.separator + Constants.RULES_FILE);
			OMElement rulesDocument = builder.getDocumentElement();
			Iterator it1 = rulesDocument.getChildElements();
			while (it1.hasNext()) {
				OMElement rule = (OMElement) it1.next();
				if (rule.getLocalName().equals("policyRule")) {
					if (rule.getFirstChildWithName(new QName("policyType"))
							.getText().trim().equals(policy.getPolicyType())) {
						OMElement config = rule
								.getFirstChildWithName(new QName("policyConfig"));
						OMElement rampartConfig = config.getFirstElement();
						OMFactory fact = rampartConfig.getOMFactory();
						if (data.getType()
								.equals(Constants.USR_PASS_CREDENTIAL)) {
							OMElement user = fact
									.createOMElement(new QName(rampartConfig
											.getNamespace().getNamespaceURI(),
											"user", "ramp"));
							user.setText(((UsrPassCredentialData) data)
									.getUserName());
							OMNode app = rampartConfig.getFirstOMChild();
							app.insertSiblingBefore(user);

						}
						policyCompleted = policy.getPolicyDocument();
						policyCompleted.addChild(rampartConfig);
						break;
					}
				}
			}

			options.setProperty(RampartMessageData.KEY_RAMPART_POLICY,
					PolicyEngine.getPolicy(policyCompleted));
			client.setOptions(options);
			client.engageModule("addressing");
			client.engageModule("rampart");
			XmlObject xmlRequest = (XmlObject) clientRequest;
			OMElement soapElement = AXIOMUtil.stringToOM(xmlRequest.xmlText());
			Object response = client.sendReceive(soapElement);
			OMElement castedResp = (OMElement) response;
			XmlObject newResp = XmlObject.Factory.parse(castedResp
					.getXMLStreamReader());
			return newResp;

		} catch (AxisFault e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (XMLStreamException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (XmlException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return null;
	}
}
